package com.atguigu.gmall.payment.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.AlipayConfig;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.atguigu.gmall.common.consts.GmallConsts;
import com.atguigu.gmall.common.exception.GmallUserException;
import com.atguigu.gmall.order.vo.PayOrderVO;
import com.atguigu.gmall.payment.bean.PaymentInfoEntity;
import com.atguigu.gmall.payment.config.GmallAlipayConfig;
import com.atguigu.gmall.payment.feign.GmallOmsClient;
import com.atguigu.gmall.payment.mapper.PaymentInfoMapper;
import com.atguigu.gmall.payment.service.PaymentService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.*;

@Controller
@RequestMapping("/")
@Slf4j
public class PaymentController {
    @Resource
    GmallOmsClient omsClient;
    @Resource
    PaymentInfoMapper paymentInfoMapper;
    @Resource
    PaymentService paymentService;
    @Resource
    RabbitTemplate rabbitTemplate;
    //通知最终的支付结果：可能会多次调用
    //      需要在异步方法中更新订单支付状态、 需要保证幂等性
    @ResponseBody
    @ApiOperation("异步通知回调")
    @PostMapping("/notifyUrl")
    public String nofityUrl(HttpServletRequest request) throws Exception {
        return paymentService.nofityUrl(request);
    }
    //快速响应：验证参数 如果签名正确、支付结果正确  直接跳转到支付成功页面(后续订单状态更新等操作由异步接口完成)
    @ApiOperation("同步通知回调")
    @GetMapping("/returnUrl")
    public String returnUrl(HttpServletRequest request) throws Exception {
        return paymentService.returnUrl(request);

    }

    @ResponseBody
    @ApiOperation("访问支付宝支付页面：支付二维码")
    @GetMapping("/alipay.html")
    public String alipayHtml(@RequestParam("orderToken")String orderToken, Model model) throws UnsupportedEncodingException {
        try {
            //用户选择了支付宝支付，后端应该给用户响应支付宝的支付页面
            //1、获得初始化的AlipayClient 并提供我们自己应用在支付宝中注册得到的参数
            AlipayClient alipayClient = new DefaultAlipayClient(GmallAlipayConfig.gatewayUrl,
                    GmallAlipayConfig.app_id,
                    GmallAlipayConfig.merchant_private_key, "json", GmallAlipayConfig.charset,
                    GmallAlipayConfig.alipay_public_key, GmallAlipayConfig.sign_type);

            //2、设置支付宝生成交易二维码的请求参数
            AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
            alipayRequest.setReturnUrl(GmallAlipayConfig.return_url);
            alipayRequest.setNotifyUrl(GmallAlipayConfig.notify_url);
            //远程访问oms服务查询订单数据：orderToken
            //商户订单号，商户网站订单系统中唯一订单号，必填
            String out_trade_no = orderToken;
            //付款金额，必填
            String total_amount = "0.01";
            //查询订单数据
            PayOrderVO payOrderVO = omsClient.queryPayOrderVOByOrderToken(orderToken).getData();
            //订单名称，必填
            String subject = "gmall";
            //商品描述，可空
            String body = payOrderVO.getRemark();
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("out_trade_no",out_trade_no);
            jsonObject.put("total_amount",total_amount);
            jsonObject.put("subject",subject);
            jsonObject.put("body", Base64.getEncoder().encode(body.getBytes("UTF-8")));
            jsonObject.put("product_code","FAST_INSTANT_TRADE_PAY");
            alipayRequest.setBizContent(jsonObject.toJSONString());
            //paymentInfoEntity.getId()
            //保存交易日志：
            //查询当前订单编号是否已存在日志，如果存在代表已经当前订单已经生成过二维码
            PaymentInfoEntity paymentInfoEntity = paymentInfoMapper.selectOne(Wrappers.lambdaQuery(PaymentInfoEntity.class)
                    .eq(PaymentInfoEntity::getOutTradeNo, orderToken));
            if(paymentInfoEntity!=null){
                //paymentInfoEntity.getId();//唯一的一个交易日志的id
                throw new GmallUserException("提交过于频繁",1033);
            }
            paymentInfoEntity = new PaymentInfoEntity();
            paymentInfoEntity.setOutTradeNo(orderToken);
            paymentInfoEntity.setPaymentType(1); //1支付宝支付
            paymentInfoEntity.setSubject(subject);
            paymentInfoEntity.setCreateTime(new Date());
            paymentInfoEntity.setTotalAmount(new BigDecimal(total_amount));
            paymentInfoEntity.setPaymentStatus(0);
//            paymentInfoEntity.setTradeNo();  支付宝一个支付对应一个交易，此属性保存支付宝的交易流水号
            paymentInfoMapper.insert(paymentInfoEntity);


            //3、访问支付宝生成一个自动提交的表单页面内容
            String result = alipayClient.pageExecute(alipayRequest).getBody();
            //响应自动提交的表单给浏览器 浏览器只要渲染自动提交的表单内容 会自动访问支付宝的支付二维码页面
            System.out.println(result);
            return result;
        } catch (AlipayApiException e) {
//            e.printStackTrace();
            throw new GmallUserException("支付异常",1031);
        }
    }
    @ApiOperation("选择支付渠道")
    @GetMapping("/pay.html")
    public String payHtml(@RequestParam("orderToken")String orderToken, Model model){
        System.out.println(orderToken);
        //查询订单信息到页面中展示
        PayOrderVO payOrderVO = paymentService.queryOrder(orderToken);
        if(payOrderVO==null){
            //订单查询失败： 转发到失败页面
            //全局异常处理： 同步异常处理  异步异常处理
        }
        model.addAttribute("orderEntity",payOrderVO);
        return "pay";
    }
}
